
package util.file.xml;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

//public class TablaXml<R extends RegistroXml> {
public class TablaXml<R extends RegistroXml> {
    //private boolean nombreSeteado;
    
    //public class Derivada extends TablaXml<R> {        
    //}
            
    private String nombre;
    private final List<R> registros;
    
      
    public final void parsear(Node nTabla, String tagRegistro, Class<R> claseInstancias) throws Exception {    
        if(nTabla!=null) {        
            this.setNombre( nTabla.getNodeName() );

            NodeList lsRegistro = ((Element) nTabla).getElementsByTagName(tagRegistro);
            int nr = lsRegistro.getLength();            

            for (int r = 0; r < nr; r++) {             
                R registro = claseInstancias.newInstance();                
                registro.parsear(lsRegistro.item(r));//Node nRegistro = hTabla;
                this.addRegistro(registro);
            }    
        }
    }
    

    public List<R> getRegistros() {
        return registros;
    }
    
    //Solucion temporal
    //http://stackoverflow.com/questions/3437897/how-to-get-class-instance-of-generics-type-t
    public TablaXml() {
        //nombreSeteado = false;
        registros = new ArrayList<R>();
    }
    
    /*
    public R newInstance() 
            throws InstantiationException, IllegalAccessException  {
       return typeParameterClass.newInstance();
    }
    */

    public void setNombre(String nombre) {
        //if(!nombreSeteado) {
            this.nombre = nombre.trim();        
            //nombreSeteado = true;//para que solo se pueda setear una sola vez el nombre
        //}
    }

    public String getNombre() {
        return nombre;
    }

    @Override
    public String toString() {
        return "Tabla{" + "nombre=" + nombre + "; nroRegistros=" + registros.size() +"}";
    }

    public void addRegistro(R registro) {
        registros.add(registro);
        registro.tabla = this;//referencia a la tabla del registro
    }

       
    /*
    public String scriptUpdate(TablaSql tsql) {
        StringBuilder sb = new StringBuilder();
        for(RegistroXml r: registros) {
            sb.append(r.scriptUpdate(tsql));
        }
        return sb.toString();
    }*/
        
    /*
    public String scriptInsert() {
        StringBuilder sb = new StringBuilder();
        for(RegistroXml r: registros) {
            sb.append(r.scriptInsert());
        }
        return sb.toString();
    }
    */

    public List<String> getCampos() throws Exception {
        //System.out.println("NOMBRE="+nombre);
        if(!tieneRegistros())
            throw new Exception("La tabla "+nombre+" no tiene campos");
        
        List<String> lista = new ArrayList<String>();
        RegistroXml r = registros.get(0);        
        for(Map.Entry<String,CampoXml> e : r.valores.entrySet()) {
            lista.add(e.getKey());
        }
        //Map<String, String> treeMap = new TreeMap<String, String>(unsortMap);        
        return lista;
    }
    
    
    public String getCamposString() throws Exception {
        StringBuilder sb = new StringBuilder();        
        for(String campo : this.getCampos()) {
            sb.append(campo);
            sb.append(",");
        }
        int n = sb.length();
        sb.delete(n-1,n);//borrando la ultima coma
        return sb.toString();
    }

    public boolean tieneRegistros() {
        //return registros.size()!=0;
        return !registros.isEmpty();
    }
    
    public int getTamaho() {
        return registros.size();
    }

    
    //protected RegistroXml newRegistroInstancia() {
    //   return new RegistroXml();
    //}


   


}
